package com.siyoumi.app.modules.app_ess.service;

import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.siyoumi.app.entity.EssModule;
import com.siyoumi.app.entity.EssQuestion;
import com.siyoumi.app.modules.app_ess.vo.VoEssQuestion;
import com.siyoumi.app.modules.app_ess.vo.VoEssQuestionAddBatch;
import com.siyoumi.app.service.EssQuestionService;
import com.siyoumi.component.XApp;
import com.siyoumi.component.XBean;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.service.IWebService;
import com.siyoumi.util.XJson;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XSqlStr;
import com.siyoumi.util.XStr;
import com.siyoumi.validator.XValidator;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

//题目
@Slf4j
@Service
public class SvcEssQuestion
        implements IWebService {
    static public SvcEssQuestion getBean() {
        return XSpringContext.getBean(SvcEssQuestion.class);
    }

    static public EssQuestionService getApp() {
        return EssQuestionService.getBean();
    }


    /**
     * 获取题目ID
     *
     * @param moduleId
     * @param type
     */
    public List<String> getIds(String moduleId, Integer type, Integer limit) {
        InputData inputData = InputData.getIns();
        inputData.put("module_id", moduleId);
        inputData.put("type", type.toString());

        JoinWrapperPlus<EssQuestion> query = listQuery(inputData);
        query.last(XSqlStr.limitX(limit));
        query.select("etqu_id");
        return getApp().getMaps(query).stream().map(item -> (String) item.get("etqu_id"))
                .collect(Collectors.toList());
    }

    public JoinWrapperPlus<EssQuestion> listQuery() {
        return listQuery(InputData.getIns());
    }

    public JoinWrapperPlus<EssQuestion> listQuery(String notTestId) {
        InputData inputData = InputData.getIns();
        inputData.put("not_test_id", notTestId);

        return listQuery(inputData);
    }

    /**
     * select
     *
     * @return query
     */
    public JoinWrapperPlus<EssQuestion> listQuery(InputData inputData) {
        String id = inputData.input("id");
        String name = inputData.input("name");
        String moduleId = inputData.input("module_id");
        String type = inputData.input("type");
        String questionType = inputData.input("question_type");
        String level = inputData.input("level");
        String notTestId = inputData.input("not_test_id");
        Boolean all = "1".equals(inputData.input("all"));

        JoinWrapperPlus<EssQuestion> query = getApp().join();
        query.eq("etqu_x_id", XHttpContext.getX());
        if (!all) {
            query.eq("etqu_del", 0);
        }

        if (XStr.hasAnyText(id)) { //id
            query.eq("etqu_id", id);
        } else {
            if (XStr.hasAnyText(name)) { //题目
                query.like("etqu_question", name);
            }
            if (XStr.hasAnyText(moduleId)) { //场景
                List<String> moduleIds = List.of(moduleId.split(","));
                query.in("etqu_module_id", moduleIds);
            }
            if (XStr.hasAnyText(type)) { //类型
                query.eq("etqu_type", type);
            } else {
                query.in("etqu_type", 0, 1);
            }
            if (XStr.hasAnyText(questionType)) { //题型
                query.eq("etqu_question_type", questionType);
            } else {
                query.in("etqu_question_type", 0, 1);
            }
            if (XStr.hasAnyText(level)) { //难度
                query.eq("etqu_level", level);
            } else {
                query.in("etqu_level", 0, 5, 10);
            }
            if (XStr.hasAnyText(notTestId)) { //过滤此评测的题目
                String sqlExists = "SELECT 1 FROM wx_app_x.t_ess_test_question WHERE etques_question_id = etqu_id AND etques_test_id = {0}";
                query.notExists(sqlExists, notTestId);
            }
        }


        return query;
    }

    public XReturn edit(InputData inputData, VoEssQuestion vo) {
        List<String> ignoreField = new ArrayList<>();
        if (inputData.isAdminEdit()) {
            //ignoreField.add("etqu_acc_id");
        }
        //答案
        Collections.sort(vo.getAnswer()); //从小到大排序
        vo.setEtqu_answer(XJson.toJSONString(vo.getAnswer()));
        //选择项
        vo.setEtqu_question_item(XJson.toJSONString(vo.getQuestion_item()));
        return XApp.getTransaction().execute(status -> {
            XReturn r = getApp().saveEntity(inputData, vo, true, ignoreField);
            //更新数量
            updateQuestionTotal(vo.getEtqu_module_id());
            //
            return r;
        });
    }

    /**
     * 批量添加题目
     */
    @Transactional(rollbackFor = Exception.class)
    public XReturn addBatch(VoEssQuestionAddBatch vo) {
        List<VoEssQuestion> importList = vo.getUpload_data();
        if (importList == null || importList.isEmpty()) {
            return EnumSys.ERR_VAL.getR("导入数据异常");
        }
        Integer rowIndex = 1;
        for (VoEssQuestion item : importList) {
            XValidator.isNullOrEmpty(item.getEtqu_question(), rowIndex + "：题目不能为空");
            if (item.getAnswer().isEmpty()) {
                XValidator.err(EnumSys.ERR_VAL.getR(rowIndex + "：答案不能为空"));
            }
            if (item.getQuestion_item().isEmpty()) {
                XValidator.err(EnumSys.ERR_VAL.getR(rowIndex + "：题目选项不能为空"));
            }
        }

        List<EssQuestion> list = new ArrayList<>();
        for (VoEssQuestion item : importList) {
            //答案
            Collections.sort(item.getAnswer()); //从小到大排序
            item.setEtqu_answer(XJson.toJSONString(item.getAnswer()));
            //选择项
            item.setEtqu_question_item(XJson.toJSONString(item.getQuestion_item()));

            EssQuestion entity = new EssQuestion();
            XBean.copyProperties(item, entity);
            entity.setEtqu_x_id(XHttpContext.getX());
            entity.setEtqu_module_id(vo.getEtqu_module_id());
            entity.setEtqu_type(vo.getEtqu_type());
            entity.setEtqu_acc_id(vo.getEtqu_acc_id());
            entity.setAutoID();

            list.add(entity);
        }
        getApp().saveBatch(list);

        updateQuestionTotal(vo.getEtqu_module_id());

        return EnumSys.OK.getR();
    }

    /**
     * 删除
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn delete(List<String> ids) {
        XReturn r = XReturn.getR(0);

        JoinWrapperPlus<EssQuestion> query = listQuery();
        query.in(EssQuestion.tableKey(), ids);
        List<EssQuestion> list = getApp().get(query);
        //for (EssQuestion entity : list) {
        //    if (entity.getEtqu_answer_total() > 0) {
        //        return XReturn.getR(20203, entity.getEtqu_question() + "：已使用，不能删除");
        //    }
        //}

        getApp().delete(ids);

        return r;
    }


    /**
     * 题目数量
     *
     * @param moduleId
     */
    public void updateQuestionTotal(String moduleId) {
        JoinWrapperPlus<EssQuestion> query = SvcEssQuestion.getBean().listQuery();
        query.select("etqu_type", "COUNT(*) total");
        query.eq("etqu_module_id", moduleId);
        query.groupBy("etqu_type");
        List<Map<String, Object>> list = SvcEssQuestion.getApp().getMaps(query);
        Long type0 = 0L;
        Long type1 = 0L;
        for (Map<String, Object> item : list) {
            Integer type = (Integer) item.get("etqu_type");
            Long total = (Long) item.get("total");
            switch (type) {
                case 0:
                    type0 = total;
                    break;
                case 1:
                    type1 = total;
                    break;
            }
        }

        //更新数量
        EssModule entityUpdate = new EssModule();
        entityUpdate.setEmod_id(moduleId);
        entityUpdate.setEmod_question0(type0);
        entityUpdate.setEmod_question1(type1);
        SvcEssModule.getApp().updateById(entityUpdate);
    }

    /**
     * 更新答题人数和答对人数
     *
     * @param questionId
     * @param addAnswer
     * @param addAnswerBingo
     */
    public void updateAnswerTotal(String questionId, Integer addAnswer, Integer addAnswerBingo) {
        int addAnswerErr = addAnswer - addAnswerBingo; //错题数
        if (addAnswerErr < 0) {
            addAnswerErr = 0;
        }

        UpdateChainWrapper<EssQuestion> update = getApp().update()
                .setSql("etqu_answer_total = etqu_answer_total + " + addAnswer)
                .setSql("etqu_answer_bingo_total = etqu_answer_bingo_total + " + addAnswerBingo)
                .setSql("etqu_answer_error_total = etqu_answer_error_total + " + addAnswerErr)
                .eq(EssQuestion.tableKey(), questionId);

        update.update();
    }
}
